package com.ddpt.permission.service.login;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import com.lh.center.activity.api.dubbo.ActivityDubboService;
import com.lh.center.common.constant.GlobalConstant;
import com.lh.center.common.constant.RedisPrefix;
import com.lh.center.common.dto.LoginByPhoneDto;
import com.lh.center.common.exception.CommonException;
import com.lh.center.common.exception.ErrorEnum;
import com.lh.center.common.util.AssertUtil;
import com.lh.center.common.web.session.SessionOperation;
import com.lh.center.mall.api.dubbo.DubboMallService;
import com.lh.center.merchant.api.dubbo.DubboMerchantInsService;
import com.lh.center.merchant.api.dubbo.DubboMerchantService;
import com.lh.center.merchant.api.dubbo.DubboPageService;
import com.lh.center.merchant.api.entity.Merchant;
import com.lh.center.merchant.api.entity.MerchantIns;
import com.lh.center.permission.api.session.TingtangSessionUser;
import com.lh.center.permission.service.LoginService;
import com.lh.center.tingtang.api.dubbo.DubboTingtangInfoService;
import com.lh.center.tingtang.api.dubbo.DubboTingtangUserService;
import com.lh.center.tingtang.api.entity.TingtangInfoEntity;
import com.lh.center.tingtang.api.entity.TingtangUserEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service("tingtangLoginService")
public class TingtangLoginServiceImpl implements LoginService<TingtangSessionUser> {

    @DubboReference
    private DubboPageService dubboPageService;

    @DubboReference
    private DubboMallService dubboMallService;

    @DubboReference
    private ActivityDubboService activityDubboService;


    @DubboReference
    private DubboTingtangUserService dubboTingtangUserService;

    @DubboReference
    private DubboMerchantService dubboMerchantService;

    @DubboReference
    private DubboMerchantInsService dubboMerchantInsService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private DubboTingtangInfoService dubboTingtangInfoService;



    @Override
    public TingtangSessionUser loginByPassword(String account, String password, String imgCode, String codeId) {
        return loginByPassword(account, password);
    }

    @Override
    public TingtangSessionUser loginByPassword(String account, String password) {
        if (StringUtils.isBlank(password)) {
            throw new CommonException(ErrorEnum.NOT_TINGTANG_USER);
        }
        String passwordStr = DigestUtil.md5Hex(password.getBytes());
        TingtangUserEntity tingtangUserEntity = dubboTingtangUserService.queryByUserAndPassWord(account, passwordStr);
        if (Objects.isNull(tingtangUserEntity)) {
            throw new CommonException(ErrorEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        if (tingtangUserEntity.getStatus()==GlobalConstant.ZERO){
            throw new CommonException(ErrorEnum.ADMIN_INVALID);
        }
        return loginByUser(tingtangUserEntity);
    }

    private TingtangSessionUser loginByUser(TingtangUserEntity tingtangUserEntity){
        if(null == tingtangUserEntity) {
            throw new CommonException(ErrorEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        if(GlobalConstant.ZERO.equals(tingtangUserEntity.getStatus())) {
            throw new CommonException(ErrorEnum.ADMIN_INVALID);
        }
        return loginSuccess(tingtangUserEntity);
    }

    @Override
    public TingtangSessionUser loginByPhone(LoginByPhoneDto dto) {

        Long merchantId = null;
        Long insId = null;

        if (StringUtils.isNotBlank(dto.getTingtangCode())){
            TingtangInfoEntity tingtangInfoEntity = dubboTingtangInfoService.getByCode(dto.getActCode());
            AssertUtil.isNull(tingtangInfoEntity,"未知厅堂");
            merchantId = tingtangInfoEntity.getMerchantId();
            insId = tingtangInfoEntity.getInsId();
        }
        if (StringUtils.isBlank(dto.getTingtangCode())){
            Merchant merchant = dubboMerchantService.getByMerchantCode(dto.getMerchantCode());
            AssertUtil.isTrue(Objects.isNull(merchant),"无此商户");
            merchantId = merchant.getId();
            MerchantIns merchantIns = dubboMerchantInsService.getMerchantTopMerchantInsByMerchantId(merchantId);
            insId = merchantIns.getId();
        }

        String phone = dto.getPhone();
        String code = dto.getCode();

        AssertUtil.isTrue(StringUtils.isBlank(dto.getPhone()),"未知手机号码");
        AssertUtil.isTrue(StringUtils.isBlank(dto.getCode()),"验证码缺失");
        String phoneCode = stringRedisTemplate.opsForValue().get(RedisPrefix.PHONE_CODE + phone);

        AssertUtil.isTrue(StringUtils.isBlank(phoneCode),"验证码已失效");
        AssertUtil.isTrue(!code.equals(phoneCode),"验证码错误");


        // 补充手机号
        //replenishPhone(dto, merchantId);

        TingtangUserEntity user = dubboTingtangUserService.getUserByPhone(merchantId, insId, phone);
        /*if(user.isNewRegister() && StringUtils.isBlank(user.getUnionId())){
            user.setUnionId(phone);
            dubboUserService.fillUnionId(user.getId(),user.getUnionId());
        }*/
        AssertUtil.isTrue(Objects.isNull(user),"该账户不存在，请联系管理员");
        if (user.getStatus()==GlobalConstant.ZERO){
            throw new CommonException(ErrorEnum.ADMIN_INVALID);
        }
        stringRedisTemplate.delete(RedisPrefix.PHONE_CODE + phone);
        return loginSuccess(user);
    }

    @Override
    public void signOut(String token) {

    }

    @Override
    public TingtangSessionUser autoLogin(Long merchantId, String phone, String randomSecret) {
        // 自动登陆的时候 notes 2022-08-22
        TingtangUserEntity user = dubboTingtangUserService.getUserByPhone(merchantId, null, phone);
        if(user == null){
            throw new CommonException("用户不存在");
        }
        if(StringUtils.isBlank(user.getRandomSecret()) || !user.getRandomSecret().equals(randomSecret)){
            throw new CommonException(ErrorEnum.user_not_login);
        }
        return loginSuccess(user);
    }


    public TingtangSessionUser loginSuccess(TingtangUserEntity user){
        TingtangSessionUser sessionUser = new TingtangSessionUser();
        //生成随机密码，并覆盖之前的
        user.setRandomSecret(UUID.randomUUID().toString().replace("-",""));
        String clientIP = ServletUtil.getClientIP(SessionOperation.getRequest());
        dubboTingtangUserService.updateLastRequest(user.getId(),user.getRandomSecret(),clientIP);
        sessionUser.setAccount(user.getPhone());
        sessionUser.setPhone(user.getPhone());
        sessionUser.setNickName(user.getNickName());
        sessionUser.setRealName(user.getRealName());
        sessionUser.setHeadImage(user.getHeadImage());
        sessionUser.setRandomSecret(user.getRandomSecret());
        //sessionUser.setNewRegister(user.isNewRegister());
        // set 基础信息 end
        sessionUser.setUserId(user.getId());
        // notes 用户的机构id和瑞丰的机构id区分开 瑞丰用insIdStr字段。
        sessionUser.setInsId(user.getInsId());
        sessionUser.setMerchantId(user.getMerchantId());
        Merchant merchant = dubboMerchantService.getById(user.getMerchantId());
        sessionUser.setMerchantName(merchant.getName());
        String token = UUID.randomUUID().toString().replace("-","");
        sessionUser.setToken(token);
        //是否开启加解密
        if(SessionOperation.getConfiguration().isEnableSecret()){
            sessionUser.setSecret(RandomUtil.randomString(16));
            sessionUser.setSecretEnabled(true);
        }
        stringRedisTemplate.opsForValue().set(RedisPrefix.USER_TINGTANG_USER_TOKEN+token, JSONUtil.toJsonStr(sessionUser),30, TimeUnit.MINUTES);
        return sessionUser;
    }


}
